第二十章 ESP32的空中升级(OTA) |
您所在的位置:网站首页 › esp32 MQTT ota Ubuntu › 第二十章 ESP32的空中升级(OTA) |
static void ota_example_task(void *pvParameter) { esp_err_t err; /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */ esp_ota_handle_t update_handle = 0 ; const esp_partition_t *update_partition = NULL;
ESP_LOGI(TAG, "Starting OTA example..."); //获取OTA app存放的位置 const esp_partition_t *configured = esp_ota_get_boot_partition(); //获取当前系统执行的固件所在的Flash分区 const esp_partition_t *running = esp_ota_get_running_partition();
if (configured != running) { ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x", configured->address, running->address); ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)"); } ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", running->type, running->subtype, running->address);
//等待wifi连上后进行OTA,项目中可以使升级命令进入OTA xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to Server....");
//连http服务器 if (connect_to_http_server()) { ESP_LOGI(TAG, "Connected to http server"); } else { ESP_LOGE(TAG, "Connect to http server failed!"); task_fatal_error(); }
//组http包发送 const char *GET_FORMAT = "GET %s HTTP/1.0\r\n" "Host: %s:%s\r\n" "User-Agent: esp-idf/1.0 esp32\r\n\r\n";
char *http_request = NULL; int get_len = asprintf(&http_request, GET_FORMAT, EXAMPLE_FILENAME, EXAMPLE_SERVER_IP, EXAMPLE_SERVER_PORT); if (get_len < 0) { ESP_LOGE(TAG, "Failed to allocate memory for GET request buffer"); task_fatal_error(); } int res = send(socket_id, http_request, get_len, 0); free(http_request); if (res < 0) { ESP_LOGE(TAG, "Send GET request to server failed"); task_fatal_error(); } else { ESP_LOGI(TAG, "Send GET request to server succeeded"); }
//获取当前系统下一个(紧邻当前使用的OTA_X分区)可用于烧录升级固件的Flash分区 update_partition = esp_ota_get_next_update_partition(NULL); ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address); assert(update_partition != NULL); //OTA写开始 err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_begin failed, error=%d", err); task_fatal_error(); } ESP_LOGI(TAG, "esp_ota_begin succeeded");
bool resp_body_start = false, flag = true; //接收完成 while (flag) { memset(text, 0, TEXT_BUFFSIZE); memset(ota_write_data, 0, BUFFSIZE); //接收http包 int buff_len = recv(socket_id, text, TEXT_BUFFSIZE, 0); if (buff_len < 0) { //包异常 ESP_LOGE(TAG, "Error: receive data error! errno=%d", errno); task_fatal_error(); } else if (buff_len > 0 && !resp_body_start) { //包头 memcpy(ota_write_data, text, buff_len); resp_body_start = read_past_http_header(text, buff_len, update_handle); } else if (buff_len > 0 && resp_body_start) { //数据段包 memcpy(ota_write_data, text, buff_len); //写flash err = esp_ota_write( update_handle, (const void *)ota_write_data, buff_len); if (err != ESP_OK) { ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x", err); task_fatal_error(); } binary_file_length += buff_len; ESP_LOGI(TAG, "Have written image length %d", binary_file_length); } else if (buff_len == 0) { //结束包 flag = false; ESP_LOGI(TAG, "Connection closed, all packets received"); close(socket_id); } else {//未知错误 ESP_LOGE(TAG, "Unexpected recv result"); } }
ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length); //OTA写结束 if (esp_ota_end(update_handle) != ESP_OK) { ESP_LOGE(TAG, "esp_ota_end failed!"); task_fatal_error(); } //升级完成更新OTA data区数据,重启时根据OTA data区数据到Flash分区加载执行目标(新)固件 err = esp_ota_set_boot_partition(update_partition); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); task_fatal_error(); } ESP_LOGI(TAG, "Prepare to restart system!"); esp_restart(); return ; } |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |